/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __X_COMMON_H__
#define __X_COMMON_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stddef.h> /* for size_t */
#include <stdint.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/
/* macro ---------------------------------------------------------------------*/

/**
 * offset_of - caculate the offset for a member in a struct
 * @t: the type of the container struct this is embedded in
 * @m: the name of the member within the struct
 */
#ifndef offset_of
#define offset_of(t, m) ((uintptr_t)&((t *)0)->m)
#endif

/**
 * container_of - cast a member of a structure out to the containing structure
 * @p: the pointer to the member
 * @t: the type of the container struct this is embedded in
 * @m: the name of the member within the struct
 */
#ifndef container_of
#define container_of(p, t, m) ((t *)(((char *)(p)) - (offset_of(t, m))))
#endif

/**
 * round_up - make a value to be aligned forward
 * @x: the value to be aligned
 * @a: the alignment value
 */
#ifndef round_up
#define round_up(x, a) (((uintptr_t)(x) + ((uintptr_t)(a) - 1)) & ~((uintptr_t)(a) - 1))
#endif

/**
 * round_down - make a value to be aligned backward
 * @x: the value to be aligned
 * @a: the alignment value
 */
#ifndef round_down
#define round_down(x, a) ((uintptr_t)(x) & ~((uintptr_t)(a) - 1))
#endif

/**
 * align_at - check if a value is aligned
 * @x: the value to be checked
 * @a: the alignment value
 */
#ifndef aligned_at
#define aligned_at(x, a) (((uintptr_t)(x) & ((uintptr_t)(a) - 1)) == 0)
#endif

/**
 * min - get the min value of two
 * @x: the 1st value
 * @y: the 2nd value
 */
#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif

/**
 * min - get the max value of two
 * @x: the 1st value
 * @y: the 2nd value
 */
#ifndef max
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif

/**
 * STATIC_ASSERT - assert at compile time
 * @e: the expression checked
 */
#ifndef STATIC_ASSERT
#define STATIC_ASSERT(e) typedef int __static_assert[(e) ? 1 : -1]
#endif

/**
 * ARRAY_SIZE - get the number of elements for an array
 * @a: the array name
 */
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif

/**
 * __CONCAT - make a new symbol by join two sub-strings
 * @s1: string 1
 * @s2: string 2
 */
#ifdef __CONCAT
#undef __CONCAT
#endif

#define __CONCAT_RAW(s1, s2) s1##s2
#define __CONCAT(s1, s2)     __CONCAT_RAW(s1, s2)

/**
 * __CVTSTR - create a string as string -> "string"
 * @s: the input string
 */
#define __CVTSTR_RAW(s) #s
#define __CVTSTR(s)     __CVTSTR_RAW(s)

/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __X_COMMON_H__ */
